home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr26
/
netprog.zip
/
NETPROG.TAR
/
ping
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-17
|
5KB
|
181 lines
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1987 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)ping.c 4.10 (Berkeley) 10/10/88";
#endif /* not lint */
#include "defs.h"
/*
* P I N G . C
*
* Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
* measure round-trip-delays and packet loss across network paths.
*
* Author -
* Mike Muuss
* U. S. Army Ballistic Research Laboratory
* December, 1983
* Modified at Uc Berkeley
*
* Status -
* Public Domain. Distribution Unlimited.
*
* Bugs -
* More statistics could always be gathered.
* This program has to run SUID to ROOT to access the ICMP socket.
*/
char usage[] = "Usage: ping [ -drv ] host [ datasize ] [ npackets ]\n";
char hnamebuf[MAXHOSTNAMELEN];
char *pname;
main(argc, argv)
int argc;
char **argv;
{
int sockoptions, on;
char *destdotaddr;
char *host_err_str();
struct hostent *host;
struct protoent *proto;
on = 1;
pname = argv[0];
argc--;
argv++;
sockoptions = 0;
while (argc > 0 && *argv[0] == '-') {
while (*++argv[0]) switch (*argv[0]) {
case 'd':
sockoptions |= SO_DEBUG;
break;
case 'r':
sockoptions |= SO_DONTROUTE;
break;
case 'v':
verbose++;
break;
}
argc--, argv++;
}
if (argc < 1)
err_quit(usage);
/*
* Assume the host is specified by numbers (Internet dotted-decimal)
* and call inet_addr() to convert it. If that doesn't work, then
* assume its a name and call gethostbyname() to look it up.
*/
bzero((char *) &dest, sizeof(dest));
dest.sin_family = AF_INET;
if ( (dest.sin_addr.s_addr = inet_addr(argv[0])) != INADDR_NONE) {
strcpy(hnamebuf, argv[0]);
hostname = hnamebuf;
destdotaddr = NULL;
} else {
if ( (host = gethostbyname(argv[0])) == NULL) {
err_quit("host name error: %s %s",
argv[0], host_err_str());
}
dest.sin_family = host->h_addrtype;
bcopy(host->h_addr, (caddr_t) &dest.sin_addr, host->h_length);
hostname = host->h_name;
destdotaddr = inet_ntoa(dest.sin_addr.s_addr);
/* convert to dotted-decimal notation */
}
/*
* If the user specifies a size, that is the size of the data area
* following the ICMP header that is transmitted. If the data area
* is large enough for a "struct timeval", then enable timing.
*/
if (argc >= 2)
datalen = atoi(argv[1]);
else
datalen = DEF_DATALEN;
packsize = datalen + SIZE_ICMP_HDR;
if (packsize > MAXPACKET)
err_quit("packet size too large");
if (datalen >= SIZE_TIME_DATA)
timing = 1;
/*
* The user can specify the maximum number of packets to receive.
*/
if (argc > 2)
npackets = atoi(argv[2]);
/*
* Fetch our Unix process ID. We use that as the "ident" field
* in the ICMP header, to identify this process' packets.
* This allows multiple copies of ping to be running on a host
* at the same time. This identifier is needed to separate
* the received ICMP packets (since all readers of an ICMP
* socket get all the received packets).
*/
ident = getpid() & 0xffff;
/*
* Create the socket.
*/
if ( (proto = getprotobyname("icmp")) == NULL)
err_quit("unknown protocol: icmp");
if ( (sockfd = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0)
err_sys("can't create raw socket");
if (sockoptions & SO_DEBUG)
if (setsockopt(sockfd, SOL_SOCKET, SO_DEBUG, &on,
sizeof(on)) < 0)
err_sys("setsockopt SO_DEBUG error");
if (sockoptions & SO_DONTROUTE)
if (setsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE, &on,
sizeof(on)) < 0)
err_sys("setsockopt SO_DONTROUTE error");
printf("PING %s", hostname);
if (destdotaddr)
printf(" (%s)", destdotaddr);
printf(": %d data bytes\n", datalen);
tmin = 99999999;
setlinebuf(stdout); /* one line at a time */
signal(SIGINT, sig_finish); /* to let user stop program */
signal(SIGALRM, sig_alarm); /* invoked every second */
sig_alarm(); /* start the output going */
recv_ping(); /* and start the receive */
/* NOTREACHED */
}